########################################################################
# iofield.py - Declares the {Input,Output}Field classes used to build
#	in the program's GUI, and a FieldSet class for managing sets of
#	fields.
#
# Created 2006.08.31 by Warren Young
#
# Copyright (c) 2006 by Pixel Corps.  This program may be used under
# the terms of the X11 license, a copy of which should have accompanied
# this program, in the LICENSE file.
########################################################################

import wx


#### class IOField #####################################################

class IOField:
	# Class-level data, for associating all child controls with their
	# parent window.
	parent = None
	eventHandler = None


#### class InputField ##################################################

class InputField(IOField):
	"""Holds a static text control and its associated edit field, plus
	an optional 'comment' in a static text control following the edit
	field."""

	def __init__(self, label, width, comment = None, height = -1,
			hardLimit = False, handler = None, value = '',
			id = wx.ID_ANY):
		editStyle = 0
		if height > 0:
			editStyle = wx.TE_MULTILINE
			height = height * 18

		self.label = wx.StaticText(self.parent, wx.ID_ANY,
				'%s: ' % label, style = wx.ALIGN_RIGHT)

		if value == None: value = ''
		self.edit = self.valueCtrl = wx.TextCtrl(self.parent, id,
				value, size = (width * 10, height), style = editStyle)
		if hardLimit:
			self.edit.SetMaxLength(width)
		if handler:
			self.eventHandler.Bind(wx.EVT_TEXT, handler, self.edit)

		if comment:
			self.comment = wx.StaticText(self.parent, wx.ID_ANY,
					comment, style = wx.ALIGN_RIGHT |
					wx.ALIGN_CENTER_VERTICAL)

			self.field = wx.FlexGridSizer(cols = 2, hgap = 10, vgap = 0)
			self.field.AddGrowableCol(1)
			self.field.Add(self.edit,
					flag = wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
			self.field.Add(self.comment,
					flag = wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
		else:
			self.field = self.edit


#### class OutputField ##################################################

class OutputField(IOField):
	"""Hold two static text controls in the same configuration as an
	InputField with no comment."""

	def __init__(self, label, value = ''):
		self.label = wx.StaticText(self.parent, wx.ID_ANY,
				'%s: ' % label, style = wx.ALIGN_RIGHT)
		self.field = self.valueCtrl = wx.StaticText(self.parent,
				wx.ID_ANY, value)


#### class FieldSet ####################################################

class FieldSet:
	"""Manages a list of IOField subclasses, and provides facilities for
	manipulating the values held in those fields."""

	def __init__(self, *fields):
		self.fields = []
		for f in fields:
			self.Append(f)


	def __len__(self):
		return len(self.fields)


	def __getitem__(self, n):
		return self.fields[n]


	def Append(self, field):
		self.fields.append(field)


	def GetFieldByName(self, name_):
		"""Return a field control (text edit or static text control)
		given a case-insensitive fragment of its label."""
		name = name_.lower()
		for f in self.fields:
			if f.label.GetTitle().lower().find(name) >= 0:
				return f.valueCtrl
		return None


	def GetValueByName(self, name_):
		"""Return a field's value given a case-insensitive fragment of
		its label."""
		f = self.GetFieldByName(name_)
		if f:
			if isinstance(f, wx.TextCtrl):
				return f.GetValue()
			else:
				return f.GetLabel()
		else:
			return None

